package com.gbr.screenrecorder;

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;

import com.gbr.application.model.Capture;

public class ScreenRecorder {
    private Robot       robot;
    protected Capture   capture;
    protected Rectangle captureArea;
    private String      captureName;
    protected float     fps       = 10;
    private boolean     recording = false;
    private Thread      thread;

    public ScreenRecorder(Rectangle area, String name) {
        this.captureArea = area;
        this.captureName = name;
    }

    public void startRecording() {
        if (thread != null) {
            return;
        }

        initializeRecording();

        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                recording = true;
                long deltaTime = Math.round(1000.0f / fps);

                // need to know the time to record one frame
                long timeToRecordOneFrame = computeFrameRecordingTime();

                while (recording) {
                    capture.addFrame(recordFrame(), (int) deltaTime);
                    try {
                        // sleep for deltaTime minus the time to record one
                        // frame
                        Thread.sleep(deltaTime - timeToRecordOneFrame);
                    } catch (InterruptedException e) {
                        // nothing
                    }
                }
                finalizeRecording();
            }
        });
        thread.start();
    }

    private long computeFrameRecordingTime() {
        long before = System.currentTimeMillis();
        recordFrame();
        long after = System.currentTimeMillis();

        return (after - before);
    }

    public void stopRecording() {
        recording = false;
        thread = null;
    }

    public Capture getCapture() {
        return capture;
    }

    protected void initializeRecording() {
        capture = new Capture(captureName, captureArea);

        try {
            robot = new Robot();
        } catch (AWTException awe) {
            awe.printStackTrace();
        }
    }

    protected void finalizeRecording() {}

    private BufferedImage recordFrame() {
        BufferedImage image = robot.createScreenCapture(captureArea);
        return image;
    }

}
